﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Sherwood.SignOn.Server.Models;
using Sherwood.SignOn.Server.Models.ViewModels;
using Sherwood.Mvc.Localization;
using Sherwood.SignOn.Server.Models.Repositories;
using Sherwood.SignOn.Server.Models.Services;

namespace Sherwood.SignOn.Server.Controllers
{
    /// <summary>
    /// Provides services to 3rd party applications such as Authentication and user profile retrieval 
    /// </summary>
    public class ServicesController : ControllerBase
    {

        /// <summary>
        /// Services/Authenticate action
        /// Authenticates user based on username and password.
        /// </summary>
        /// <param name="model">Required model parameters:
        /// -ClientCode
        /// -Timestamp
        /// -Signature
        /// -Username
        /// -Password</param>
        /// <returns>Empty string if user was not authenticated, UserProfile XML if user was authenticated.</returns>
        public ActionResult Authenticate(AuthenticateServiceViewModel model)
        {
            try
            {
                IUserAccount account = model.AuthenticateUser();
                if (account != null)
                {
                    return Content(Data.UserProfiles.GetBasicProfileXml(account, model.ClientCode));
                }
                return Content("");
            }
            catch (Exception ex)
            {
                serviceException exceptionXml = new serviceException();
                exceptionXml.message = ex.Message ?? "";
                exceptionXml.innerException = ex.InnerException != null && ex.InnerException.Message != null ? ex.InnerException.Message : "";
                exceptionXml.stackTrace = ex.StackTrace ?? "";
                return Content(exceptionXml.ToString());
            }
        }

        /// <summary>
        /// Services/GetUserProfile action
        /// Returns user profile to trusted clients. 
        /// </summary>
        /// <param name="model">Required model parameters:
        /// -ClientCode
        /// -Timestamp
        /// -Signature
        /// -UserAccountId, Email or Username</param>
        /// <returns>UserProfile XML if information could be successfully retreived</returns>
        public ActionResult GetUserProfile(GetUserProfileServiceViewModel model)
        {
            try
            {
                IUserAccount account = model.GetUserProfile();
                if (account != null)
                {
                    return Content(Data.UserProfiles.GetBasicProfileXml(account, model.ClientCode));
                }
                throw new Exception("User account profile could not be retreived.");
                //return Content("");
            }
            catch (Exception ex)
            {
                serviceException exceptionXml = new serviceException();
                exceptionXml.message = ex.Message ?? "";
                exceptionXml.innerException = ex.InnerException != null && ex.InnerException.Message != null ? ex.InnerException.Message : "";
                exceptionXml.stackTrace = ex.StackTrace ?? "";
                return Content(exceptionXml.ToString());
            }
        }

        /// <summary>
        /// Services/IsSessionActive action
        /// This action allows trusted clients to check if a user session is active.
        /// </summary>
        /// <param name="model">Required model parameters:
        /// -ClientCode
        /// -Timestamp
        /// -Signature
        /// -SignOnSessionId</param>
        /// <returns>UserProfile XML if users session is active (and client could be verified), otherwise an empty string.</returns>
        public ActionResult GetSessionProfile(IsSessionActiveViewModel model)
        {
            try
            {
                IUserSession session = model.CheckSession();
                if (session != null)
                {
                    return Content(Data.UserProfiles.GetSessionProfileXml(session, model.ClientCode));
                }
                throw new Exception("Session could not be retreived.");
            }
            catch (Exception ex)
            {
                serviceException exceptionXml = new serviceException();
                exceptionXml.message = ex.Message ?? "";
                exceptionXml.innerException = ex.InnerException != null && ex.InnerException.Message != null ? ex.InnerException.Message : "";
                exceptionXml.stackTrace = ""; //don't really want to send a stacktrace to clients!
                return Content(exceptionXml.ToString());
            }
        }

        /// <summary>
        /// Returns the current date from the server as a string
        /// </summary>
        /// <returns></returns>
        public ActionResult Ping()
        {
            return Content(DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"));
        }
    }
}
